package com.atguigu.gmall.activity.service.impl;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.model.activity.OrderRecode;
import com.atguigu.gmall.model.activity.SeckillGoods;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class SeckillGoodsServiceImpl implements SeckillGoodsService {


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    /**
     * 查询所有秒杀数据
     * @return
     */
    @Override
    public List<SeckillGoods> seckillGoodList() {

        List<SeckillGoods> seckillGoods = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).values();

        if (!CollectionUtils.isEmpty(seckillGoods)){
            return seckillGoods;
        }

        return null;

    }


    /**
     * 查询商品秒杀详情
     * @param skuId
     * @return
     */
    @Override
    public SeckillGoods getSeckillGood(Long skuId) {

        SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.opsForHash().get(RedisConst.SECKILL_GOODS,skuId.toString());

        if (seckillGoods!=null){
            return seckillGoods;
        }
        return null;
    }

    /**
     *     完成用户预下单
     * @param skuId
     * @param userId
     */
    @Override
    public void seckillOrder(Long skuId, String userId) {

//        判断商品状态是否
        String state = (String) CacheHelper.get(skuId.toString());
        if (state.equals("0")){
//            已售完
            return;
        }
        //判断用户是否下单
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(RedisConst.SECKILL_USER +
                userId, skuId,RedisConst.SECKILL__TIMEOUT,TimeUnit.SECONDS);
        if (!flag){
//            已经下过单
            return;
        }
//        可以下单，从redis队列获取订单
        String goods = (String) redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX+skuId).rightPop();
        if (StringUtil.isEmpty(goods)){
//            已售完,更改商品状态
            redisTemplate.convertAndSend("seckillpush",skuId+":0");
            return;
        }
        //订单数据存入Reids
        OrderRecode orderRecode = new OrderRecode();
        orderRecode.setUserId(userId);
        orderRecode.setOrderStr(DigestUtils.md5DigestAsHex((skuId+userId).getBytes()));
        orderRecode.setSeckillGoods(getSeckillGood(skuId));//调用方法查询
        orderRecode.setNum(1);
//        抢到订单存入秒杀的商品信息
        redisTemplate.opsForHash().put(RedisConst.SECKILL_ORDERS,userId,orderRecode);

//        更新库存信息
        updateStockCount(skuId);
    }
    //        更新库存信息
    private void updateStockCount(Long skuId) {

//        查询redis中数据更新库存
        Long count = redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX + skuId).size();

//        防止频繁跟新数据库
        if (count%2==0){
//            更新redis
            SeckillGoods seckillGood = getSeckillGood(skuId);
            seckillGood.setStockCount(count.intValue());
            redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).put(skuId.toString(),seckillGood);

//            更新数据库
            seckillGoodsMapper.updateById(seckillGood);
        }
    }

    /**
     * 显示页面轮询接口
     * @param skuId
     * @param userId
     * @return
     * 1.  判断用户是否在缓存中存在
     * 2.  判断用户是否抢单成功
     * 3.  判断用户是否下过订单
     * 4.  判断状态位
     */
    @Override
    public Result checkOrder(Long skuId, String userId) {
////        判断用户是否在缓存中存在
        String userKey = RedisConst.SECKILL_USER + userId;
        Boolean falg = redisTemplate.hasKey(userKey);
//        存在
        if (falg){
//            判断用户是否抢单成功
            String orderKey = RedisConst.SECKILL_ORDERS;
            Boolean result = redisTemplate.boundHashOps(orderKey).hasKey(userId);
            if (result){
//                返回抢单成功, 查询商品详情
                OrderRecode  orderRecode = (OrderRecode) redisTemplate.boundHashOps(orderKey).get(userId);
                return Result.build(orderRecode,ResultCodeEnum.SECKILL_SUCCESS);
            }
        }
//        判断用户是否已经下过订单
        String ordersUserKey = RedisConst.SECKILL_ORDERS_USERS;
        Boolean res = redisTemplate.boundHashOps(ordersUserKey).hasKey(userId);
        if (res){
//            获取订单数据
            String orderId = (String) redisTemplate.boundHashOps(ordersUserKey).get(userId);
            return Result.build(orderId,ResultCodeEnum.SECKILL_ORDER_SUCCESS);
        }
//        判断商品状态
        String state = (String) CacheHelper.get(skuId.toString());
        if (state.equals("0")){
            return Result.build(null,ResultCodeEnum.SECKILL_FINISH);
        }
//        默认排队中
        return Result.build(null,ResultCodeEnum.SECKILL_RUN);
    }

    }
